// RedisGeoService.java
package net.jgrm.redisadvanced.service;

import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.domain.geo.Metrics;

import java.util.List;
import java.util.Map;

/**
 * Redis GEO 地理位置服务接口
 */
public interface RedisGeoService<T> {

    /**
     * 添加地理位置信息
     *
     * @param key       Redis key
     * @param member    成员名称
     * @param longitude 经度
     * @param latitude  纬度
     * @return 添加结果
     */
    Long addLocation(String key, T member, double longitude, double latitude);

    /**
     * 批量添加地理位置信息
     *
     * @param key       Redis key
     * @param locations 位置信息 Map<member, Point>
     * @return 添加成功的数量
     */
    Long addLocations(String key, Map<T, Point> locations);

    /**
     * 获取指定成员的地理位置
     *
     * @param key     Redis key
     * @param members 成员列表
     * @return 位置信息列表
     */
    List<Point> getLocations(String key, T... members);

    /**
     * 计算两个成员之间的距离
     *
     * @param key     Redis key
     * @param member1 成员1
     * @param member2 成员2
     * @param metric  距离单位 (默认为米)
     * @return 距离
     */
    Distance getDistance(String key, T member1, T member2, Metrics metric);

    /**
     * 获取指定位置附近的成员（按距离排序）
     *
     * @param key       Redis key
     * @param longitude 经度
     * @param latitude  纬度
     * @param radius    半径
     * @param metric    距离单位
     * @param count     返回结果数量限制
     * @return 按距离排序的结果
     */
    GeoResults<RedisGeoCommands.GeoLocation<T>> getNearbyLocations(
            String key, double longitude, double latitude, double radius,
            Metrics metric, long count);

    /**
     * 获取指定成员附近的成员（按距离排序）
     *
     * @param key    Redis key
     * @param member 成员
     * @param radius 半径
     * @param metric 距离单位
     * @param count  返回结果数量限制
     * @return 按距离排序的结果
     */
    GeoResults<RedisGeoCommands.GeoLocation<T>> getNearbyLocations(
            String key, T member, double radius,
            Metrics metric, long count);

    /**
     * 获取指定位置附近的成员（仅返回成员名称）
     *
     * @param key       Redis key
     * @param longitude 经度
     * @param latitude  纬度
     * @param radius    半径
     * @param metric    距离单位
     * @return 成员名称列表
     */
    List<T> getNearbyLocationNames(String key, double longitude, double latitude,
                                   double radius, Metrics metric);

    /**
     * 删除指定成员
     *
     * @param key     Redis key
     * @param members 成员列表
     * @return 删除成功的数量
     */
    Long removeLocations(String key, T... members);
}
